#pragma once

namespace hHashVectorDetail
{
	template <typename Val>
	struct Node;
	template <typename Val, bool IsConst>
	class Iterator;
}

template <typename Val>
struct hHashVector
{
	using POwnerPtr = std::shared_ptr<hHashVector*>;
	using Node = hHashVectorDetail::Node<Val>;
	using PNode = Node*;
	using PNodePtr = std::shared_ptr<PNode>;
	using Iter = hHashVectorDetail::Iterator<Val, false>;
	using CIter = hHashVectorDetail::Iterator<Val, true>;

	POwnerPtr _ppSelf;
	PNode _pNode = NULL;

	hHashVector();
	hHashVector(hHashVector&& v);
	~hHashVector();
	hHashVector& operator=(hHashVector&& v);

	template<typename... Args>
	Iter emplace(size_t k, Args... args);
	void erase(size_t k);
	void erase(Iter it);
	Iter find(size_t k);
	void clear();

	bool empty() const;
	size_t num() const;

	Iter begin();
	static Iter end() { return Iter(); }

	Val& operator[] (size_t k) { return *(*emplace(k)._ppNode)->_val; }
	template <typename Func>
	auto show(std::ostream& os, Func func) const->std::ostream&;
};

#include "hHashVectorImpl.h"
#include "hHashVectorNodeImpl.h"
#include "hHashVectorIteratorImpl.h"
